//
//  @ Project : Galaxy Star Trading System
//  @ File Name : Order.cpp
//  @ Date : 2014/9/5
//  @ Author :
//
//

#include "../StdInc.h"
#include <boost/format.hpp>
using namespace boost;

namespace GSTrader
{
	namespace TradeBase
	{
		CInputOrder::CInputOrder() : m_nID(-1), m_nEntrustID(-1), m_nStrategyID(-1), m_nProviderId(-1), m_InstrumentId(-1), m_strInstrumentID(""),
			m_dPrice(0), m_nOrderPriceType(0), m_nQty(0), m_nSpecialKey(-1), m_strOrigOrdId("")
			, m_nStatus(osNotSent), m_strDirection(""), m_nOpenClose(0), m_nSide(0), m_nHedgeFlag(0), m_strCreateTime(""), m_nSessionId(-1), m_nFrontId(-1),
			m_nSubmitStatus(ossNoUse), m_nPortfolioId(-1), m_nActionType(oatNewOrder)
		{
			m_nTimeInForce = tiGfd;		
			m_strExchangeID = "";
			m_nVolumeCondition = vcAV;  
			m_nErrorId = 0;
		}

		CInputOrder::~CInputOrder()
		{

		}

		string CInputOrder::GetKey()
		{
			format fmt("%d%d%s");
			fmt % m_nSessionId;
			fmt % m_nFrontId;
			fmt % m_strOrigOrdId;

			return fmt.str();
		}


		COrder::COrder() : CInputOrder(), m_dFrozenPremium(0), m_dAvgPrice(0), m_CumQty(0), m_LeavesQty(0), m_StatusMsg(""), m_dStopPx(0),
			m_strConfirmId(""), m_dFrozenMargin(0), m_strTradingDay(""), m_dFroZenCommision(0), m_strReportTime(""), m_strInsertDate(""), m_strLastTradeTime("")
		{

		}

		COrder::COrder(CExcutionMessage* pMessage)
		{
			assert(false);
		}

		COrder::COrder(int nProviderId,
		               int nStrategyID,
		               string strInstrumentID,
		               string strExchangeID,
		               int nPortfolioId,
		               int nSide,
		               int nOpenClose,
		               int nHedgeflag,
		               double dPrice,
		               int nVol,
		               int nOrderPriceType,
		               string strDirection,
		               double dStopPrice,
		               double dStopProfitPrice)
			: COrder()
		{
			m_nStrategyID = nStrategyID;
			m_nProviderId = nProviderId;
			m_nPortfolioId = nPortfolioId;
			m_strInstrumentID = strInstrumentID;
			m_strExchangeID = strExchangeID;
			m_nSide = nSide;
			m_nOpenClose = nOpenClose;
			m_nHedgeFlag = nHedgeflag;
			m_dPrice = dPrice;
			m_nQty = nVol;
			m_nOrderPriceType = nOrderPriceType;
			m_strDirection = strDirection;
			m_dStopPx = dStopPrice;

		}

		COrder::~COrder()
		{

		}

		bool COrder::Equals(COrder* pOrder)
		{
			if (pOrder == NULL)
				return false;

			return !m_strInstrumentID.empty() &&
			       m_strInstrumentID == pOrder->m_strInstrumentID &&
			       m_nOpenClose == pOrder->m_nOpenClose &&
			       m_nSide == pOrder->m_nSide &&
			       m_nHedgeFlag == pOrder->m_nHedgeFlag &&
			       m_nStatus == pOrder->m_nStatus;
		}

		COrder& COrder::operator = (const COrder& r)
		{
			m_nID				= r.m_nID;
			m_nStrategyID		= r.m_nStrategyID;
			m_nEntrustID		= r.m_nEntrustID;
			m_nProviderId		= r.m_nProviderId;
			m_nPortfolioId		= r.m_nPortfolioId;
			m_InstrumentId		= r.m_InstrumentId;
			m_strInstrumentID	= r.m_strInstrumentID;
			m_nSpecialKey		= r.m_nSpecialKey;
			m_dPrice			= r.m_dPrice;
			m_nErrorId			= r.m_nErrorId;
			m_nOrderPriceType	= r.m_nOrderPriceType;
			m_dAvgPrice			= r.m_dAvgPrice;
			m_dFrozenMargin		= r.m_dFrozenMargin;
			m_dFroZenCommision	= r.m_dFroZenCommision;
			m_dFrozenPremium	= r.m_dFrozenPremium;
			m_nQty				= r.m_nQty;
			m_CumQty			= r.m_CumQty;
			m_LeavesQty			= r.m_LeavesQty;
			m_nStatus			= r.m_nStatus;
			m_nTimeInForce		= r.m_nTimeInForce;
			m_StatusMsg			= r.m_StatusMsg;
			m_strExchangeID		= r.m_strExchangeID;
			m_nOpenClose		= r.m_nOpenClose;
			m_nSide				= r.m_nSide;
			m_nHedgeFlag		= r.m_nHedgeFlag;
			m_nVolumeCondition	= r.m_nVolumeCondition;
			m_strOrigOrdId		= r.m_strOrigOrdId;
			m_strTradingDay		= r.m_strTradingDay;

			m_strConfirmId		= r.m_strConfirmId;
			m_strCreateTime		= r.m_strCreateTime;
			m_strReportTime		= r.m_strReportTime;
			m_strInsertDate		= r.m_strInsertDate;
			m_strLastTradeTime	= r.m_strLastTradeTime;

			m_nFrontId			= r.m_nFrontId;
			m_nSessionId		= r.m_nSessionId;
			m_nSubmitStatus		= r.m_nSubmitStatus;
			m_strDirection		= r.m_strDirection;
			m_dStopPx			= r.m_dStopPx;
			return *this;
		}

		COrder::COrder(const COrder& r)
		{
			*this = r;
		}

		COrder::COrder(const COrder* pOrder)
		{
			*this = *pOrder;
		}

		bool COrder::IsBuy()
		{
			return m_nSide == osBuy;
		}

		bool COrder::IsPending()//
		{
			if ((m_nStatus == osPendingNew) || (m_nStatus == osPendingCancel))
				return true;
			else
				return false;
		}

		bool COrder::IsTraded()
		{
			return (m_nStatus == osAllTraded ||
			        m_nStatus == osTouched);
		}

		bool COrder::IsNoTrade()
		{
			return (m_nStatus == osNoTradeQueueing ||
			        m_nStatus == osNoTradeNotQueueing ||
			        m_nStatus == osPartTradedQueueing ||
			        m_nStatus == osPartTradedNotQueueing ||
			        m_nStatus == osPendingNew ||
			        m_nStatus == osUnknown ||
			        m_nStatus == osNotTouched)
			       &&
			       (m_nSubmitStatus != ossNewOrderActionInsert &&
			        m_nSubmitStatus != ossInsertRejected ||
			        m_nSubmitStatus != ossCancelRejected ||
			        m_nSubmitStatus != ossModifyRejected
			       );
			m_nStatus;
			m_nSubmitStatus;
		}

		bool COrder::IsClose()
		{
			return ::IsClose(m_nOpenClose);
		}

		void COrder::Reset()
		{
			m_nStatus = osNotSent;
			m_nSubmitStatus = ossNoUse;
			m_nActionType = oatNewOrder;
		}

		bool COrder::IsFinal()
		{
			return m_nStatus == osAllTraded ||
			       m_nStatus == osPartTradedNotQueueing ||
			       m_nStatus == osNoTradeNotQueueing ||
			       m_nStatus == osCanceled ||
			       m_nStatus == osTouched ||
			       m_nSubmitStatus == ossInsertRejected ||
			       m_nSubmitStatus == ossCancelRejected ||
			       m_nSubmitStatus == ossModifyRejected;
		}

		bool COrder::IsRejected()
		{
			return 	m_nSubmitStatus == ossNewOrderRejected ||
			        m_nSubmitStatus == ossInsertRejected ||
			        m_nSubmitStatus == ossCancelRejected ||
			        m_nSubmitStatus == ossModifyRejected;
		}

		void COrder::CopyIDFrom(COrder& r)
		{
			m_nID = r.m_nID;
			m_InstrumentId = r.m_InstrumentId;
			m_nEntrustID = r.m_nEntrustID;
			m_nStrategyID = r.m_nStrategyID;
			m_nPortfolioId = r.m_nPortfolioId;
		}

		void COrder::SetOrderRejected()
		{
			if (m_nStatus == osNotSent)
			{
				m_nSubmitStatus = ossNewOrderRejected;
			}
			else
			{
				assert(false);
			}
		}

		bool COrder::IsCanceled()
		{
			return m_nStatus == osCanceled &&
			       m_nSubmitStatus != ossCancelRejected;
		}

		CInstrumentLongCode COrder::GetLongCode()
		{
			return CInstrumentLongCode(m_strInstrumentID, m_strExchangeID);
		}

		string COrder::ToString()
		{
			format fmt(g_language == slChinese ? Chinese::c_szFmt7 : English::c_szFmt7);
			fmt % m_strInstrumentID;
			fmt % (g_language == slChinese ? Chinese::GetOrderSideType(m_nSide) : English::GetOrderSideType(m_nSide));
			fmt % (g_language == slChinese ? Chinese::GetOpenCloseType(m_nOpenClose) : English::GetOpenCloseType(m_nOpenClose));
			fmt % m_nQty;
			fmt % m_dPrice;
			
			fmt % m_strCreateTime;

			return fmt.str();
		}

		void COrder::ProcessExecutionReport(CExecutionReport* pReport)
		{
			assert(pReport != NULL);
			if (pReport->m_nExecType == ExecAllTraded || pReport->m_nExecType == ExecPartTraded)
			{
				
			}
		}

		void COrder::ProcessExecutionCommond(CMsg* pMsg)
		{

		}

		CReplaceOrder::CReplaceOrder()
		{

		}

		CReplaceOrder::~CReplaceOrder()
		{

		}
	}
}